package com.util;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.configuration.XMLConfiguration;

import com.protocol.Protocol;
import com.qy.util.LogUtil;
import com.qy.util.ServerConfigUtil;
import com.socket.Command;


/**
 * 命令处理类
 */
public class CommandMgr {

	private static Map<Short, Command> commandMap = new HashMap<Short, Command>();

	/**
	 * 初始化配置
	 */
	public static boolean init() {
		String type = null;
		String clazz = null;
		try {
			XMLConfiguration config = new XMLConfiguration(ServerConfigUtil.getPath("command.path"));
			List<Object> types = config.getList("command[@type]");
			List<Object> classes = config.getList("command[@class]");
			if (types.size() != classes.size()) {
				LogUtil.error("init command config file, types and classes num not equal");
				return false;
			}
			int size = types.size();
			for (int i = 0; i < size; i++) {
				type = (String) types.get(i);
				clazz = (String) classes.get(i);
				commandMap.put(parseType(type), parseClass(clazz));
			}
		} catch (Exception e) {
			LogUtil.error("init command config file error, server start failed. type: " + type + " clazz: " + clazz, e);
			return false;
		}
		
		return true;
	}


	/**
	 * 缓存中获取命令
	 */
	public static Command getCommand(short code) {
		return commandMap.get(code);
	}


	/**
	 * 解析type
	 */
	@SuppressWarnings("unchecked")
	private static short parseType(String type) throws Exception {
		int index = type.lastIndexOf(".");
		String classType = type.substring(0, index);
		String fieldType = type.substring(index + 1, type.length());
		Class<Protocol> clazz = (Class<Protocol>) Class.forName(classType);
		Field field = clazz.getField(fieldType);
		return field.getShort(clazz);
	}

	/**
	 * 解析Class
	 */
	@SuppressWarnings("unchecked")
	private static Command parseClass(String clazzStr) throws Exception {
		Class<Command> clazz = (Class<Command>) Class.forName(clazzStr);
		Command cmd = clazz.newInstance();
		return cmd;
	}
	
}
